home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / domcli.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-10  |  14.3 KB  |  628 lines

  1. #include <ctype.h>
  2. #include <io.h>
  3. #include <dos.h>
  4.  
  5. #include "global.h"
  6. #include "config.h"
  7. #include "domain.h"
  8. #include "socket.h"
  9. #include "netuser.h"
  10. #include "files.h"
  11. #include "cmdparse.h"
  12.  
  13. struct dserver *Dlist = NULLDOM;
  14.  
  15. #ifdef ENH
  16. static struct rr *Rrlist[NRLIST];
  17. #endif
  18.  
  19. int Dhaveaa = 1;
  20. int DBloaded = 0;
  21. int Db_initialize = 0;
  22. int DTranslate = 0;
  23. int DVerbose = 1;
  24. int Dcache_size = 20;
  25. int Cwrite = 0;
  26.  
  27. static int16 Dtimeout = 60;
  28. int16 Dretries = 2;
  29.  
  30. char *Dsuffix = NULLCHAR;
  31.  
  32. int Dstypes[] = {
  33.     TYPE_SOA,
  34.     TYPE_NS,
  35.     TYPE_MX,
  36.     TYPE_MD,
  37.     TYPE_MF,
  38.     TYPE_CNAME,
  39.     TYPE_PTR,
  40.     TYPE_A,
  41.     TYPE_MB,
  42.     TYPE_MG,
  43.     TYPE_MR,
  44.     TYPE_NULL,
  45.     TYPE_WKS,
  46.     TYPE_HINFO,
  47.     TYPE_MINFO,
  48.     TYPE_TXT,
  49.     0
  50. };
  51.  
  52. /*----------------------------------------------------------------------*
  53. * list the cache entries                                                *
  54. *-----------------------------------------------------------------------*/
  55. static int
  56. docachelist(argc,argv,p)
  57. int argc;
  58. char *argv[];
  59. void *p;
  60. {
  61. int i;
  62. char buf[80];
  63. Cache *cap = cache;
  64.  
  65.    tputs("Status   Address            Name\n");
  66.    for (i = 0; i < Dcache_size; i++) {
  67.       if(i == Dcache_size)
  68.          break;
  69.       if (cap->ti) {
  70.          sprintf(buf,"%u.%u.%u.%u",            /* always print the ip-address */
  71.             hibyte(hiword(cap->address)),   /* even if DTranslate is set   */
  72.             lobyte(hiword(cap->address)),
  73.             hibyte(loword(cap->address)),
  74.             lobyte(loword(cap->address)) );
  75.          tprintf("%-9.9s%-19s%s\n",
  76.             (cap->type == Found) ? "Valid" : "Invalid",buf,cap->name);
  77.       }
  78.       cap++;
  79.    }
  80.    return(0);
  81. }
  82.  
  83. static int
  84. docachegarb(int argc,char *argv[],void *p)
  85. {
  86. int i;
  87. Cache *cap = cache;
  88.  
  89.    semwait(&Cwrite,1);
  90.  
  91.    for(i = 0; i < Dcache_size; i++) {
  92.       if(cap->type == Missing || cap->address == 0) {
  93.          cap->ti = 0;
  94.          memset(cap->name,0,5);
  95.       }
  96.       cap++;
  97.    }
  98.    semrel(&Cwrite);
  99.    return 0;
  100. }
  101.  
  102. /*----------------------------------------------------------------------*
  103. * change the cache size
  104. *-----------------------------------------------------------------------*/
  105. static int
  106. docachesize(argc,argv,p)
  107. int argc;
  108. char *argv[];
  109. void *p;
  110. {
  111. int result = 0, newsize = Dcache_size;
  112.  
  113.    if ((result = setintrc(&(int16)newsize,"DOM cache size",argc,argv,2,50)) == 0) {
  114.        if(argc > 1 && newsize > 0){
  115.           semwait(&Cwrite,1);               /* lock again                   */
  116.           Dcache_size = newsize;
  117.           xfree(cache);
  118.           cache = cxallocw(sizeof(Cache),(newsize + 2));
  119.           semrel(&Cwrite);
  120.        }
  121.    }
  122.    return result;
  123. }
  124.  
  125. static int
  126. doadds(argc,argv,p)
  127. int argc;
  128. char *argv[];
  129. void *p;
  130. {
  131.     struct dserver *dp;
  132.     int32 address;
  133.  
  134.     if((address = resolve(argv[1])) == 0){
  135.         tprintf(Badhost,argv[1]);
  136.         return 1;
  137.     }
  138.     if(address == Ip_addr) {
  139.         tputs("Use 'start domain'\n");
  140.     } else {
  141.         dp = (struct dserver *)mxallocw(sizeof(struct dserver));
  142.         dp->address = address;
  143.         dp->port = (argc < 3) ? IPPORT_DOMAIN : atoi(argv[2]);
  144.  
  145.         /* Pick a wait time for response: it takes about 15 sec on my AT
  146.          * to scan trough the domain.txt file. Taking 3 scans (max)
  147.          * and giving a little strech to the channel i come to 60 secs */
  148.         dp->srtt = dp->timeout = Dtimeout * 1000L;
  149.         dp->mdev = 0;
  150.         dp->next = Dlist;
  151.         Dlist = dp;
  152.         Dhaveaa = 0;             /* another is also responsible */
  153.     }
  154.     return 0;
  155. }
  156.  
  157. static int
  158. dodfile(argc,argv,p)
  159. int argc;
  160. char *argv[];
  161. void *p;
  162. {
  163.     if(argc < 2 && Dfile != NULLCHAR)
  164.         tprintf("%s\n",Dfile);
  165.     else {
  166.         if(access(argv[1],0) == 0) {
  167.             xfree(Dfile);
  168.             Dfile = strxdup(argv[1]);
  169.         } else {
  170.             tputs("No such domain file\n");
  171.             return -1;
  172.         }
  173.     }
  174.     return 0;
  175. }
  176.  
  177. static int
  178. dodropds(argc,argv,p)
  179. int argc;
  180. char *argv[];
  181. void *p;
  182. {
  183.     struct dserver *dp, *dptmp = NULLDOM;
  184.     int32 addr;
  185.  
  186.     if((addr = resolve(argv[1])) == 0) {
  187.         tprintf(Badhost,argv[1]);
  188.     } else {
  189.         for(dp = Dlist; dp != NULLDOM; dptmp = dp, dp = dp->next)
  190.             if(dp->address == addr) {
  191.                 if(dptmp != NULLDOM)
  192.                     dptmp->next = dp->next;
  193.                 else
  194.                     Dlist = dp->next;
  195.                 xfree((char *)dp);
  196.                 if(Dlist == NULLDOM)
  197.                     Dhaveaa = 1;
  198.                 return 0;
  199.         }
  200.     }
  201.     return -1;
  202. }
  203.  
  204. static int
  205. dolistds(argc,argv,p)
  206. int argc;
  207. char *argv[];
  208. void *p;
  209. {
  210.     struct dserver *dp;
  211.  
  212.     tputs("Server          srtt    mdev    timeout queries responses timeouts\n");
  213.     for(dp = Dlist; dp != NULLDOM; dp = dp->next) {
  214.         tprintf("%-16s%-8lu%-8lu%-8lu%-8lu%-10lu%-8lu\n",
  215.             inet_ntoa(dp->address),
  216.             dp->srtt,dp->mdev,dp->timeout,
  217.             dp->queries,dp->responses,dp->missers);
  218.     }
  219.     return 0;
  220. }
  221.  
  222. #ifdef ENH
  223. static int
  224. doload(argc,argv,pp)
  225. int argc;
  226. char *argv[];
  227. void *pp;
  228. {
  229.     FILE *dbase;
  230.     int type, numbscan = 0, numbload = 0;
  231.     long rrsize = 0;
  232.     struct rr *rrp, *rrl, *db_SOA;
  233.     struct rr_memory *memory;
  234.     char *arg[2];
  235.     char Recload[] = "Number of %srecords scanned %d loaded %d\n";
  236.  
  237.     arg[0] = NULLCHAR;
  238.     arg[2] = NULLCHAR;
  239.  
  240.     if((dbase = open_file((argc < 3) ? Dfile : argv[1],READ_TEXT,0,1)) == NULLFILE)
  241.         return 1;
  242.     memory = (struct rr_memory *)mxallocw(sizeof(struct rr_memory));
  243.  
  244.     db_SOA = NULLRR;
  245.  
  246.     if(Lorigin == NULLDLIST) {
  247.         Lorigin = (struct dlist *)mxallocw(sizeof(struct dlist));
  248.         Lorigin->name = ""; /* start with empty domain name */
  249.         Db_initialize = 1;
  250.         while((rrp = get_rr(dbase,memory)) != NULLRR) {
  251.             type = rrp->type;
  252.             numbscan++;
  253.             numbload++;
  254.             rrsize += (long)rrp->rdlength;
  255.             if(type == TYPE_SOA)
  256.                 db_SOA = rrp;   /* save for reference */
  257.             else
  258.                 rrp->soarec = db_SOA;
  259.             if(Rrlist[type] == NULLRR) {
  260.                 Rrlist[type] = rrp; /* initialize linked list */
  261.                 Rrlistl[type] = rrp;
  262.             } else {
  263.                 Rrlistl[type]->next = rrp;
  264.                 Rrlistl[type] = rrp; /* append to linked list */
  265.             }
  266.         }
  267.         /* Lorigin stayes as a list of loaded domain origin names.
  268.          * it is refered to in rrp->origins loaded in memory.
  269.          * having a common origin saves significantly in used
  270.          * memory oposed to giving every record a copy of that
  271.          * origin. Domain save will reconstruct $origin statements.
  272.          */
  273.         tprintf(Recload,"",numbscan,numbload);
  274.         tprintf("Memory record size %d extra %ld\n",sizeof(struct rr),rrsize);
  275.         Db_initialize = 0;
  276.         Dorigin = NULLCHAR; /* not loading anymore */
  277.         DBloaded = 1;       /* disable domain file access */
  278.     } else {
  279.         Db_initialize = 1;
  280.         while((rrp = get_rr(dbase,memory)) != NULLRR) {
  281.             numbscan++;
  282.             type = rrp->type;
  283.             if(type == TYPE_SOA)
  284.                 db_SOA = rrp;   /* save for reference */
  285.             else
  286.                 rrp->soarec = db_SOA;
  287.             fflush(stdout);
  288.             if(add_rr(NULLFILE,rrp))
  289.                 free_rr(rrp);
  290.             else
  291.                 numbload++;
  292.         }
  293.         tprintf(Recload,"additional ",numbscan,numbload);
  294.         Db_initialize = 0;
  295.         Dorigin = NULLCHAR; /* not loading anymore */
  296.         fclose(dbase);
  297.         xfree((char *)memory);
  298.         return 0;
  299.     }
  300.     fclose(dbase);
  301.     xfree(memory->dorigin);
  302.     xfree((char *)memory);
  303.     if((rrp = Rrlist[TYPE_NS]) != NULLRR) {
  304.         rrl = rrp;
  305.         while(rrl != NULLRR) {
  306.             arg[1] = rrl->rdata.name;
  307.             doadds(2,arg,pp);
  308.             rrl = rrl->next;
  309.         }
  310.     }
  311.     return 0;
  312. }
  313. #endif
  314.  
  315. #ifdef ENH
  316. static int
  317. donslookup(argc,argv,p)
  318. int argc;
  319. char *argv[];
  320. void *p;
  321. {
  322.     int i, len, type = 0;
  323.     int16 flags;
  324.     int32 address;
  325.     char *buf;
  326.     struct dhdr *dhdr;
  327.     struct mbuf *bp;
  328.  
  329.     if((address = resolve(argv[1])) == 0) {
  330.         tprintf(Badhost,argv[1]);
  331.         return 1;
  332.     }
  333.     if(isdigit(*argv[2])) {
  334.         type = atoi(argv[2]);
  335.         if(type > 255)
  336.             type = 0;
  337.     } else {
  338.         for(i = 0; i < NRLIST; i++) {
  339.             if(stricmp(argv[2],type2str(i)) == 0){
  340.                 type = i;
  341.                 break;
  342.             }
  343.         }
  344.     }
  345.     if(type == 0){
  346.         tprintf("Unknown record type %s\n",argv[2]);
  347.         return 1;
  348.     }
  349.  
  350.     flags = DOM_DORECURSE | DOM_CANRECURSE; /* Recursion desired */
  351.     dhdr = bld_dhdr(QUERY,QUERY,flags,NO_ERROR,argv[3],CLASS_IN,type);
  352.     buf = mxallocw(512);
  353.     len = res_mkbuf(dhdr,buf,512);
  354.     free_dhdr(dhdr);
  355.     for(;;) {
  356.         if(sendquery(address,buf,len,&bp,Dtimeout * 1000) > 0) {
  357.             dhdr = (struct dhdr *)mxallocw(sizeof(struct dhdr));
  358.             ntohdomain(dhdr,&bp);
  359.             proc_answer(dhdr,NULLDOM,NULLFILE);
  360.             free_dhdr(dhdr);
  361.             tputs("NS lookup: host added\n");
  362.         } else {
  363.             tputs("NS lookup: timeout\n");
  364.         }
  365.         break;
  366.     }
  367.     return 0;
  368. }
  369. #endif
  370.  
  371. static int
  372. doretries(argc,argv,p)
  373. int argc;
  374. char *argv[];
  375. void *p;
  376. {
  377.     return setintrc(&Dretries,"DOM retries",argc,argv,1,10);
  378. }
  379.  
  380. #ifdef ENH
  381. static int
  382. dosave(argc,argv,pp)
  383. int argc;
  384. char *argv[];
  385. void *pp;
  386. {
  387.     FILE *dbase;
  388.     int i, j;
  389.     struct rr *rrp;
  390.     struct dlist *llist;
  391.     char *p;
  392.  
  393.     if((dbase = open_file((argc < 3) ? "/domain.new" : argv[1],WRITE_TEXT,0,1)) == NULLFILE)
  394.         return 1;
  395.     if((llist = Lorigin) != NULLDLIST) {
  396.         while(llist != NULLDLIST) {
  397.             fprintf(dbase,"$origin\t%s\n",llist->name);
  398.             for(i = 0, j = Dstypes[i]; (j = Dstypes[i]) != 0; i++)  {
  399.                 if((rrp = Rrlist[j]) != NULLRR) {
  400.                     while(rrp != NULLRR) {
  401.                         if((*llist->name == '\0')
  402.                           && (rrp->origin == NULLCHAR)) {
  403.                             if(rrp->type != TYPE_A)
  404.                                 put_rr(dbase,rrp,0);
  405.                             else if(rrp->rdata.addr != 0)
  406.                                 put_rr(dbase,rrp,0);
  407.                         } else if(rrp->origin == llist->name) {
  408.                             if(rrp->type != TYPE_A)
  409.                                 put_rr(dbase,rrp,0);
  410.                             else
  411.                                 if( rrp->rdata.addr != 0)
  412.                                     put_rr(dbase,rrp,0);
  413.                         }
  414.                         rrp = rrp->next;
  415.                     }
  416.                 }
  417.             }
  418.             llist = llist->next;
  419.         }
  420.     } else for(i = 0, j = Dstypes[i]; (j = Dstypes[i]) != 0; i++)  {
  421.         p = NULLCHAR;
  422.         if((rrp = Rrlist[j]) != NULLRR) {
  423.             while(rrp != NULLRR) {
  424.                 if(rrp->name[strlen(rrp->name) - 1] != '.') {
  425.                     if(p == NULLCHAR && rrp->origin != NULLCHAR)
  426.                         fprintf(dbase,"$origin %s\n",rrp->origin);
  427.                     if(p != NULLCHAR && rrp->origin == NULLCHAR)
  428.                         fputs("$origin \n",dbase);
  429.                     if(p != NULLCHAR && rrp->origin != NULLCHAR)
  430.                         if(stricmp(p,rrp->origin))
  431.                             fprintf(dbase,"$origin %s\n",rrp->origin);
  432.                     p = rrp->origin;
  433.                 }
  434.                 if(rrp->type != TYPE_A)
  435.                     put_rr(dbase,rrp,0);
  436.                 else
  437.                    if( rrp->rdata.addr != 0)
  438.                     put_rr(dbase,rrp,0);
  439.                 rrp = rrp->next;
  440.             }
  441.         }
  442.     }
  443.     fclose(dbase);
  444.     return 0;
  445. }
  446. #endif
  447.  
  448. static int
  449. dosuffix(argc,argv,p)
  450. int argc;
  451. char *argv[];
  452. void *p;
  453. {
  454.     if(argc < 2){
  455.         if(Dsuffix != NULLCHAR)
  456.             tprintf("%s\n",Dsuffix);
  457.     } else {
  458.         if(strcmp(argv[1],"none") == 0) {
  459.             xfree(Dsuffix);
  460.             Dsuffix = NULLCHAR; /* clear out suffix */
  461.         } else {
  462.             int i = strlen(argv[1]) - 1;
  463.             xfree(Dsuffix);
  464.             Dsuffix = mxallocw(i + 3);
  465.             strcpy(Dsuffix,argv[1]);
  466.             if(argv[1][i] != '.')
  467.                 strcat(Dsuffix,".");
  468.         }
  469.     }
  470.     return 0;
  471. }
  472.  
  473. static int
  474. dotimeout(argc,argv,p)
  475. int argc;
  476. char *argv[];
  477. void *p;
  478. {
  479.     return setintrc(&Dtimeout,"DOM timeout",argc,argv,2,120);
  480. }
  481.  
  482. static int
  483. dotranslate(argc,argv,p)
  484. int argc;
  485. char *argv[];
  486. void *p;
  487. {
  488.     return setbool(&DTranslate,"DOM translate",argc,argv);
  489. }
  490.  
  491. static int
  492. doverbose(argc,argv,p)
  493. int argc;
  494. char *argv[];
  495. void *p;
  496. {
  497.     return setbool(&DVerbose,"DOM verbose",argc,argv);
  498. }
  499.  
  500. #ifdef ENH
  501. static int
  502. dozoneinit(argc,argv,p)
  503. int argc;
  504. char *argv[];
  505. void *p;
  506. {
  507.     struct dhdr *dhdr;
  508.     struct dserver *dp;
  509.     struct sockaddr_in server;
  510.     int32 address;
  511.     int16 flags;
  512.     char *buf, *bootname, *domainname;
  513.     int len, s, resp;
  514.     struct mbuf *bp;
  515.     FILE *fp;
  516.     char *name = argv[1];
  517.  
  518.     if(*name == '[')
  519.         address = aton(name+1);
  520.     else
  521.         if(isaddr(name))
  522.             address = aton(name);
  523.         else {
  524.             tprintf("Can't resolve %s currently\n",argv[1]);
  525.             return 1;
  526.         }
  527.  
  528.     dp = (struct dserver *)mxallocw(sizeof(struct dserver));
  529.     dp->srtt = dp->timeout = Dtimeout * 1000;
  530.     dp->mdev = 0;
  531.  
  532.     DBloaded = 1;                   /* disable domain file access */
  533.     bootname = (argc > 2) ? argv[2] : "/domain.txt";
  534.     domainname = (argc > 3) ? argv[3] : "/domain.new";
  535.  
  536.     /* do zoneinit from remote server */
  537.     server.sin_family = AF_INET;
  538.     server.sin_port = IPPORT_DOMAIN;
  539.     server.sin_addr.s_addr = address;
  540.     flags = DOM_DORECURSE | DOM_CANRECURSE;         /* Recursion desired */
  541.     buf = mxallocw(512);
  542.     dhdr = bld_dhdr(QUERY,ZONEINIT,flags,NO_ERROR,bootname,CLASS_IN,TYPE_ANY);
  543.     len = res_mkbuf(dhdr,buf,512);
  544.     bp = qdata(buf,(int16)len);
  545.     if((fp = open_file(domainname,WRITE_TEXT,0,1)) != NULLFILE) {
  546.         if((s = socket(AF_INET,SOCK_DGRAM,0)) != -1) {
  547.             send_mbuf(s,bp,0,(char *)&server,sizeof(server));
  548.             for(;;) {
  549.                 alarm(dp->timeout);
  550.                 resp = recv_mbuf(s,&bp,0,NULLCHAR,0);
  551.                 alarm(0L);
  552.                 if(resp == -1)
  553.                     break;
  554.                 ntohdomain(dhdr,&bp);
  555.                 proc_answer(dhdr,dp,fp);
  556.             }
  557.             close_s(s);
  558.         }
  559.         fclose(fp);
  560.     }
  561.     xfree(buf);
  562.     free_dhdr(dhdr);
  563.     xfree((char *)dp);
  564.     DBloaded = 0;
  565.     return 0;
  566. }
  567. #endif
  568.  
  569. static int
  570. docache(int argc,char *argv[],void *p)
  571. {
  572.     struct cmds Dcachecmds[] = {
  573.        "garb",     docachegarb,  0, 0, NULLCHAR,
  574.        "list",   docachelist,  0, 0, NULLCHAR,
  575.        "size",   docachesize,  0, 0, NULLCHAR,
  576.        NULLCHAR,
  577.     };
  578.     return subcmd(Dcachecmds,argc,argv,p);
  579. }
  580.  
  581. int
  582. dodomain(argc,argv,p)
  583. int argc;
  584. char *argv[];
  585. void *p;
  586. {
  587.     struct cmds Dcmds[] = {
  588.         "add",    doadds,     0, 2,
  589.             "domain add <server> [<port>]",
  590.         "cache",    docache,    0, 0,
  591.             NULLCHAR,
  592.         "dfile",    dodfile,    0, 0,
  593.             NULLCHAR,
  594.         "drop",   dodropds,       0, 2,
  595.             "domain drop <server>",
  596.         "list",  dolistds,       0, 0,
  597.             NULLCHAR,
  598. #ifdef ENH
  599.         "load",     doload,     0, 0,
  600.             "domain load [<filename>]",
  601.         "nslookup", donslookup, 1024, 4,
  602.             "domain nslookup <server> <record type> <name>",
  603. #endif
  604.         "retries",  doretries,  0, 0,
  605.             NULLCHAR,
  606. #ifdef ENH
  607.         "save",     dosave,     0, 0,
  608.             "domain save [<filename>]",
  609. #endif
  610.         "suffix",   dosuffix,   0, 0,
  611.             NULLCHAR,
  612.         "timeout",  dotimeout,  0, 0,
  613.             NULLCHAR,
  614.         "translate",dotranslate,0, 0,
  615.             NULLCHAR,
  616.         "verbose",  doverbose,  0, 0,
  617.             NULLCHAR,
  618. #ifdef ENH
  619.         "zoneinit", dozoneinit, 1024, 2,
  620.             "domain zoneinit <server> [<filename>]",
  621. #endif
  622.         NULLCHAR,
  623.     };
  624.  
  625.     return subcmd(Dcmds,argc,argv,p);
  626. }
  627.  
  628.